
// Array Remove - By John Resig (MIT Licensed)
Array.prototype.remove = function(from, to) {
  var rest = this.slice((to || from) + 1 || this.length);
  this.length = from < 0 ? this.length + from : from;
  return this.push.apply(this, rest);
};

/**
* Generic data provider for
**/
jsx3.Class.defineClass(
    "ux.cdb.admin.dataautomate.GenericDetail",
    jsx3.gui.Block,
    [ux.cdb.admin.dataautomate.IDataProvider],
    function (block) {
        
        block.Student            = 'ux.cdb.admin.dataautomate.GenericDetail.Student'            ;
        block.CooperOrg          = 'ux.cdb.admin.dataautomate.GenericDetail.CooperOrg'          ;
        block.CooperAgreement    = 'ux.cdb.admin.dataautomate.GenericDetail.CooperAgreement'    ;
        block.Contract           = 'ux.cdb.admin.dataautomate.GenericDetail.Contract'           ;
        block.Receipt            = 'ux.cdb.admin.dataautomate.GenericDetail.Receipt'            ;
        block.Loan               = 'ux.cdb.admin.dataautomate.GenericDetail.Loan'               ;
        block.User               = 'ux.cdb.admin.dataautomate.GenericDetail.User'               ;
        
        block.prototype.setDataEntityType = function(val,paint){
            this.uxdataentitytype = val;
        };

        block.prototype.getDataEntityType = function(){
            return this.uxdataentitytype;
        };
        
        block.prototype.setDataEntityId = function(val,paint){
            this.uxdataentityid = val;
        };

        block.prototype.getDataEntityId = function(){
            return this.uxdataentityid;
        };
        
        block.prototype.setProcessHandler = function(func){
            if(!(func instanceof Function)) { return; }
            this.uxprocesshandler = func;
        };

        block.prototype.getProcessHandler = function(){
            return this.uxprocesshandler;
        };
        
        block.prototype.init = function(strName, vntLeft, vntTop, vntWidth, vntHeight, strHTML) {
            //call constructor for super class (the super expects the name of the object and the function that it is an instance of)
            this.jsxsuper(strName, vntLeft, vntTop, vntWidth, vntHeight, strHTML);
        };

        block.prototype.addRule = function(originNames, targetNames, ruleFun, scope) {

            if(!this.pipeRules) { this.pipeRules = []; }
            if(!this.triggerFields) { this.triggerFields = []; }

            var i, ruleIndex = this.pipeRules.length, fieldName;
            var originFields = [], targetFields = [];

            scope = scope || this;
            
            for(i = 0; i<originNames.length; i++) {
                fieldName = originNames[i];
                if(!this.get(fieldName)) {
                    ux.cdb.admin.Log.error("GernericDetail, addRule Faild! Invaild origin field name:" + fieldName);
                    return;
                }
                originFields[i] = this.get(fieldName);
            }

            for(i = 0; i<targetNames.length; i++) {
                fieldName = targetNames[i];
                if(!this.get(fieldName)) {
                    ux.cdb.admin.Log.error("GernericDetail, addRule Faild! Invaild target field name:" + fieldName);
                    return;
                }
                targetFields[i] = this.get(fieldName);
            }

            this.pipeRules[ruleIndex] = {originFields: originFields, targetFields: targetFields, ruleFun: ruleFun, scope: scope };
            for(i = 0; i<originNames.length; i++) {
                fieldName = originNames[i];
                if(!this.triggerFields[fieldName]) {
                    if(this.get(fieldName).setAsTriggerField) {
                        this.get(fieldName).setAsTriggerField();
                    }
                    this.triggerFields[fieldName] = [];
                }
                this.triggerFields[fieldName].push(ruleIndex);
            }
        };

        block.prototype.onTriggerFieldChange = function(triggerFieldName) {
            if(this.triggerFields[triggerFieldName]) {
                var i, ruleIndex, rule;
                for(i=0; i<this.triggerFields[triggerFieldName].length; i++) {
                    ruleIndex = this.triggerFields[triggerFieldName][i];
                    rule = this.pipeRules[ruleIndex];
                    rule.ruleFun.call(rule.scope, rule.originFields, rule.targetFields);
                }
            }
        };

        block.prototype.onSetParent = function(parent) {
            var me = this;
            return this.jsxsuper(parent);
        };
        
        block.prototype.doValidate = function(){
            var eIter = this.getAllExtractorsIterator();
            var summaryArr = null;
            
            while(eIter.hasNext()) {
                var ext = eIter.next();
                var ret = ext.doValidate();
                if(ret === null) { 
                    continue; 
                }
                var att = ext.getName();
                var value = ret;
                var msg = {label:ext.getLabelName(), obj:att, message:value};
                if(summaryArr === null) { 
                    summaryArr = []; 
                    try{
						ext.focusField();
					}catch(e){
						jsx3.log('can not focus this field[' + ext + ']! ErrorMessage:' + e.message);
					}
                }
                summaryArr.push(msg);
            }
            
            return summaryArr;
        };
        
        block.prototype.refreshData = function(){
            var entityType = this.getDataEntityType();
            var entityId = this.getDataEntityId();
            if(entityType == null || entityType == '' || entityId == null || entityType == '')  return;
            var namespace = dictionary[entityType].ns;
            var method = dictionary[entityType].method;
            var callback = dictionary[entityType].handler;
            
            var cacheInfo = ux.cdb.admin.Cache.get(entityType+":"+entityId);
			cacheInfo = null;  //clear cache
            if(cacheInfo == null){
                /* @JSC :: begin DEBUG */
                console.log('none cached object,requesting...id:',entityId);
                /* @JSC :: end */
                if(ux.megatron.util.JobManager.isPending(entityType+":"+entityId)){
                    /* @JSC :: begin DEBUG */
                    console.log('request job is pending,cancel the request to server');
                    /* @JSC :: end */
                    //loop wait for data has arrived.
                    var me = this;
                    var loopFunc = function(){
                        var objFromCache = ux.cdb.admin.Cache.get(entityType+":"+entityId);
                        if(objFromCache == null){
                            setTimeout(loopFunc,500);
                        }else{
                            /* @JSC :: begin DEBUG */
                            console.log('data has arrived,load from cache..obj:',objFromCache);
                            /* @JSC :: end */
                            if(me.getProcessHandler()!=null)    objFromCache = me.getProcessHandler().apply(me,[objFromCache]);
                            me.setDataByObject(objFromCache);
                        }
                    };
                    setTimeout(loopFunc,500);
                }else{
                    ux.megatron.util.JobManager.addToPending(entityType+":"+entityId);
                    ux.megatron.util.Dwr.callDwr(namespace, method, [entityId], this, callback);
                }
                
            }else{
                /* @JSC :: begin DEBUG */
                console.log('load from cache..obj:',cacheInfo);
                /* @JSC :: end */
                if(this.getProcessHandler()!=null)  cacheInfo = this.getProcessHandler().apply(this,[cacheInfo]);
                this.setDataByObject(cacheInfo);
            }
            

        };
        
        //data handler for server response.If needed ,you can write your own data handler
        var genericDataHandler = function(obj){
            var entityType = this.getDataEntityType();
            var entityId = this.getDataEntityId();      
            var fullInfo = obj.content.data[0];
            ux.cdb.admin.Cache.set(entityType+":"+entityId,fullInfo);
            if(this.getProcessHandler()!=null)  fullInfo = this.getProcessHandler().apply(this,[fullInfo]);
            this.setDataByObject(fullInfo);
            /* @JSC :: begin DEBUG */
            console.log('before remove job,identity:',entityType+":"+entityId);
            /* @JSC :: end */
            
            ux.megatron.util.JobManager.removeFromPending(entityType+":"+entityId);
            /* @JSC :: begin DEBUG */
            console.log('set into cache,obj:',fullInfo);
            /* @JSC :: end */
        };
        
        
        //helper function & dictionary
        var dictionary = {};
        dictionary[block.Student] =   {ns:"AddStudentInfoUCC",method:"getStudentDetailInfoById",handler:genericDataHandler};    
        dictionary[block.CooperOrg] = {ns:"GetCooperOrgUCC",method:"getAllInfo",handler:genericDataHandler};        
        dictionary[block.CooperAgreement] = {ns:"MaintainCooperAgreementUCC", method:"getCooperAgreementDetailinfo", handler:genericDataHandler};
        dictionary[block.Contract] =  {ns:"RetailStudentLoanContractFeedBackUCC",method:"getRetailStudentPreContractDetailInfo",handler:genericDataHandler};
        dictionary[block.Loan] =      {ns:"AcceptRetailStudentLoanAppUCC",method:"getStudentInfoByAppID",handler:genericDataHandler};
        dictionary[block.Receipt] =   {ns:"RetailStudentLoanContractFeedBackUCC", method: "getRetailContractDetailInfo", handler:genericDataHandler};
        dictionary[block.User] =      {ns:"UserMgrUCC",method:"getAllUserInfoByUserID",handler:genericDataHandler};
        
        var extendObj = function(tar,org){
            for(var prop in org){
                tar[prop] = org[prop];
            }
            return tar;
        };

        

        
        
    }
);


